package com.bootdo.core.service.impl;

import com.bootdo.common.exception.BusinessException;
import com.bootdo.common.exception.Direction;
import com.bootdo.common.exception.ErrorCode;
import com.bootdo.core.dao.ShoppingAccountFlowMapper;
import com.bootdo.core.dao.ShoppingAccountMapper;
import com.bootdo.core.domain.ShoppingAccount;
import com.bootdo.core.domain.ShoppingAccountFlow;
import com.bootdo.core.domain.ShoppingAccountFlowVo;
import com.bootdo.core.domain.Transaction;
import com.bootdo.core.service.IAccountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @author dudianbo
 * @ClassName: ${CLASSNAME}
 * @Description: 基础账户原子操作
 * @date 2018/4/23
 */
@Service
public class AccountServiceImpl implements IAccountService {
    private static Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class);
    @Autowired
    ShoppingAccountMapper shoppingAccountMapper;
    @Autowired
    ShoppingAccountFlowMapper shoppingAccountFlowMapper;

    /**
     * 账户金额增加
     */
    @Override
    public void increase(Transaction transaction) {
        if(transaction.getAmount().compareTo(BigDecimal.ZERO)>0) {
            //查询客户账户是否可用
            ShoppingAccount shoppingAccount = shoppingAccountMapper.selectAccountByUserId(transaction.getUserId());
            if (shoppingAccount == null) {
                logger.error("用户{}状态不正确", transaction.getUserId());
                throw new BusinessException(ErrorCode.ACCOUNT_ERROR_301);
            }
            //修改账户金额
            logger.info("账户{}增加前，总余额{}，冻结金额{}", shoppingAccount.getAccountNo(), shoppingAccount.getTotalAmount(), shoppingAccount.getFrozenAmount());
            BigDecimal totalAmount = shoppingAccount.getTotalAmount().add(transaction.getAmount());
            ShoppingAccount record = new ShoppingAccount();
            record.setTotalAmount(totalAmount);
            record.setAccountNo(shoppingAccount.getAccountNo());
            shoppingAccountMapper.updateAccountByAccountNo(record);
            logger.info("账户{}增加后，总余额{}，冻结金额{}", shoppingAccount.getAccountNo(), totalAmount, shoppingAccount.getFrozenAmount());

            //添加流水
            //生成流水号
            ShoppingAccountFlow accountFlow = new ShoppingAccountFlow();
            accountFlow.setAccountNo(shoppingAccount.getAccountNo());
            accountFlow.setAmount(transaction.getAmount());
            accountFlow.setOrderId(transaction.getOrderId());
            //账户明细流水号
            accountFlow.setDetailOrderId(transaction.getOrderId()+shoppingAccount.getAccountNo()+ Direction.INCREASE.getCode());
            accountFlow.setUserId(shoppingAccount.getUserId());
            accountFlow.setDirection(Direction.INCREASE.getCode());
            accountFlow.setAccountType(transaction.getAccountType());
            accountFlow.setTransationDate(new Date());
            accountFlow.setOperateType(0);
            accountFlow.setCompleteBalance(totalAmount);
            accountFlow.setRemark(transaction.getRemark());
            shoppingAccountFlowMapper.insertSelective(accountFlow);
        }
    }

    /**
     * 账户金额减少
     */
    @Override
    public void reduce(Transaction transaction) {
        if(transaction.getAmount().compareTo(BigDecimal.ZERO)>0) {
            //查询客户账户是否可用
            ShoppingAccount shoppingAccount = shoppingAccountMapper.selectAccountByUserId(transaction.getUserId());
            if (shoppingAccount == null) {
                logger.error("用户{}状态不正确", transaction.getUserId());
                throw new BusinessException(ErrorCode.ACCOUNT_ERROR_301);
            }
            //修改账户金额
            logger.info("账户{}减少前，总余额{}，冻结金额{}", shoppingAccount.getAccountNo(), shoppingAccount.getTotalAmount(), shoppingAccount.getFrozenAmount());
            BigDecimal totalAmount = shoppingAccount.getTotalAmount().subtract(transaction.getAmount());
            BigDecimal avaAmount = totalAmount.subtract(shoppingAccount.getFrozenAmount());
            if (avaAmount.compareTo(BigDecimal.ZERO) < 0||totalAmount.compareTo(BigDecimal.ZERO)<0) {
                logger.error("用户{}金额不足", shoppingAccount.getAccountNo());
                throw new BusinessException(ErrorCode.ACCOUNT_ERROR_302);
            }
            ShoppingAccount record = new ShoppingAccount();
            record.setTotalAmount(totalAmount);
            record.setAccountNo(shoppingAccount.getAccountNo());
            shoppingAccountMapper.updateAccountByAccountNo(record);
            logger.info("账户{}减少后，总余额{}，冻结金额{}", shoppingAccount.getAccountNo(), totalAmount, shoppingAccount.getFrozenAmount());

            //添加流水
            //生成流水号
            ShoppingAccountFlow accountFlow = new ShoppingAccountFlow();
            accountFlow.setAccountNo(shoppingAccount.getAccountNo());
            accountFlow.setAmount(transaction.getAmount());
            accountFlow.setOrderId(transaction.getOrderId());
            //账户明细流水号
            accountFlow.setDetailOrderId(transaction.getOrderId()+shoppingAccount.getAccountNo()+Direction.REDUCE.getCode());
            accountFlow.setUserId(shoppingAccount.getUserId());
            accountFlow.setDirection(Direction.REDUCE.getCode());
            accountFlow.setAccountType(transaction.getAccountType());
            accountFlow.setTransationDate(new Date());
            accountFlow.setOperateType(0);
            accountFlow.setCompleteBalance(totalAmount);
            accountFlow.setRemark(transaction.getRemark());
            shoppingAccountFlowMapper.insertSelective(accountFlow);
        }
    }
    /**
     * 账户金额冻结
     */
    @Override
    public void frozen(Transaction transaction) {
        if(transaction.getAmount().compareTo(BigDecimal.ZERO)>0) {
            //查询客户账户是否可用
            ShoppingAccount shoppingAccount = shoppingAccountMapper.selectAccountByUserId(transaction.getUserId());
            if (shoppingAccount == null) {
                logger.error("用户{}状态不正确", transaction.getUserId());
                throw new BusinessException(ErrorCode.ACCOUNT_ERROR_301);
            }
            //冻结账户金额
            logger.info("账户{}冻结前，总余额{}，冻结金额{}", shoppingAccount.getAccountNo(), shoppingAccount.getTotalAmount(), shoppingAccount.getFrozenAmount());
            BigDecimal frozenAmount = shoppingAccount.getFrozenAmount().add(transaction.getAmount());
            BigDecimal avaAmount = shoppingAccount.getTotalAmount().subtract(frozenAmount);
            if (avaAmount.compareTo(BigDecimal.ZERO) < 0) {
                logger.error("用户{}金额不足", shoppingAccount.getAccountNo());
                throw new BusinessException(ErrorCode.ACCOUNT_ERROR_302);
            }

            ShoppingAccount record = new ShoppingAccount();
            record.setFrozenAmount(frozenAmount);
            record.setAccountNo(shoppingAccount.getAccountNo());
            shoppingAccountMapper.updateAccountByAccountNo(record);
            logger.info("账户{}冻结后，总余额{}，冻结金额{}", shoppingAccount.getAccountNo(), shoppingAccount.getTotalAmount(), frozenAmount);

            //添加流水
            //生成流水号
            ShoppingAccountFlow accountFlow = new ShoppingAccountFlow();
            accountFlow.setAccountNo(shoppingAccount.getAccountNo());
            accountFlow.setAmount(transaction.getAmount());
            accountFlow.setOrderId(transaction.getOrderId());
            //账户明细流水号
            accountFlow.setDetailOrderId(transaction.getOrderId()+shoppingAccount.getAccountNo()+Direction.FROZEN.getCode());
            accountFlow.setUserId(shoppingAccount.getUserId());
            accountFlow.setDirection(Direction.FROZEN.getCode());
            accountFlow.setAccountType(transaction.getAccountType());
            accountFlow.setTransationDate(new Date());
            accountFlow.setOperateType(0);
            accountFlow.setCompleteBalance(shoppingAccount.getTotalAmount());
            accountFlow.setRemark(transaction.getRemark());
            shoppingAccountFlowMapper.insertSelective(accountFlow);
        }
    }
    /**
     * 账户金额解冻
     */
    @Override
    public void unFrozen(Transaction transaction) {
        if(transaction.getFrozenOrderId()!=null) {
            //查询客户账户是否可用
            ShoppingAccount accountCurrency = shoppingAccountMapper.selectAccountByUserId(transaction.getUserId());
            if (accountCurrency == null) {
                logger.error("用户{}状态不正确", transaction.getUserId());
                throw new BusinessException(ErrorCode.ACCOUNT_ERROR_301);
            }
            //冻结账户金额
            logger.info("账户{}解冻前，总余额{}，冻结金额{}", accountCurrency.getAccountNo(), accountCurrency.getTotalAmount(),  accountCurrency.getFrozenAmount());
            ShoppingAccountFlowVo accountFlowRecord=new ShoppingAccountFlowVo();
            accountFlowRecord.setOrderId(transaction.getFrozenOrderId());
            accountFlowRecord.setDirection(Direction.FROZEN.getCode());
            List<ShoppingAccountFlow> list=shoppingAccountFlowMapper.selectByrecord(accountFlowRecord);
            if(list==null||list.size()==0){
                logger.error("该冻结订单{}不存在", transaction.getFrozenOrderId());
                throw new BusinessException(ErrorCode.BUSSINESS_ERROR_206);
            }
            ShoppingAccountFlow frozenAccountFlow=list.get(0);
            BigDecimal frozenAmount = accountCurrency.getFrozenAmount().subtract(frozenAccountFlow.getAmount());
            if (frozenAmount.compareTo(BigDecimal.ZERO) < 0) {
                logger.error("用户{}冻结金额不足", accountCurrency.getAccountNo());
                throw new BusinessException(ErrorCode.ACCOUNT_ERROR_302);
            }
            ShoppingAccount record = new ShoppingAccount();
            record.setFrozenAmount(frozenAmount);
            record.setAccountNo(accountCurrency.getAccountNo());
            shoppingAccountMapper.updateAccountByAccountNo(record);
            logger.info("账户{}解冻后，总余额{}，冻结金额{}", accountCurrency.getAccountNo(), accountCurrency.getTotalAmount(),  frozenAmount);

            //添加流水
            //生成流水号
            ShoppingAccountFlow accountFlow = new ShoppingAccountFlow();
            accountFlow.setAccountNo(accountCurrency.getAccountNo());
            accountFlow.setAmount(frozenAccountFlow.getAmount());
            accountFlow.setOrderId(transaction.getOrderId());
            //账户明细流水号
            accountFlow.setDetailOrderId(transaction.getOrderId()+accountCurrency.getAccountNo()+Direction.UNFROZEN.getCode());
            accountFlow.setUserId(accountCurrency.getUserId());
            accountFlow.setDirection(Direction.UNFROZEN.getCode());
            accountFlow.setAccountType(transaction.getAccountType());
            accountFlow.setTransationDate(new Date());
            accountFlow.setOperateType(0);
            accountFlow.setCompleteBalance(accountCurrency.getTotalAmount());
            accountFlow.setOldOrderId(transaction.getFrozenOrderId());
            accountFlow.setRemark(transaction.getRemark());
            shoppingAccountFlowMapper.insertSelective(accountFlow);
        }
    }
}
